package com.wb.spring.boot.autoconfigure.client;

import com.wb.spring.boot.autoconfigure.hystrix.FallbackFactory;
import org.springframework.context.ApplicationContext;

/**
 * @author sw
 * @create 2023-03-03 10:01
 */
public class WbClientBuilder {

    private final ApplicationContext applicationContext;

    public WbClientBuilder(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public <T> Builder<T> forType(final Class<T> type, final String name) {
        return new Builder<>(this.applicationContext, type, name);
    }

    public static final class Builder<T> {

        private WbClientFactoryBean wbClientFactoryBean;

        private Builder(final ApplicationContext applicationContext, final Class<T> type,
                        final String name) {
            this.wbClientFactoryBean = new WbClientFactoryBean();

            this.wbClientFactoryBean.setApplicationContext(applicationContext);
            this.wbClientFactoryBean.setType(type);
            this.wbClientFactoryBean.setName(WbClientsRegistrar.getName(name));
            this.wbClientFactoryBean.setContextId(WbClientsRegistrar.getName(name));
            this.wbClientFactoryBean.setInheritParentContext(true);
            // preset default values - these values resemble the default values on the
            // FeignClient annotation
            this.url("").path("").decode404(false);
        }

        public Builder<T> url(final String url) {
            this.wbClientFactoryBean.setUrl(WbClientsRegistrar.getUrl(url));
            return this;
        }


        public Builder<T> contextId(final String contextId) {
            this.wbClientFactoryBean.setContextId(contextId);
            return this;
        }

        public Builder<T> path(final String path) {
            this.wbClientFactoryBean.setPath(WbClientsRegistrar.getPath(path));
            return this;
        }

        public Builder<T> decode404(final boolean decode404) {
            this.wbClientFactoryBean.setDecode404(decode404);
            return this;
        }

        public Builder<T> inheritParentContext(final boolean inheritParentContext) {
            this.wbClientFactoryBean.setInheritParentContext(inheritParentContext);
            return this;
        }

        public Builder<T> fallback(final Class<? extends T> fallback) {
            WbClientsRegistrar.validateFallback(fallback);
            this.wbClientFactoryBean.setFallback(fallback);
            return this;
        }

        public Builder<T> fallbackFactory(
                final Class<? extends FallbackFactory<? extends T>> fallbackFactory) {
            WbClientsRegistrar.validateFallbackFactory(fallbackFactory);
            this.wbClientFactoryBean.setFallbackFactory(fallbackFactory);
            return this;
        }

        /**
         * @return the created Feign client
         */
        public T build() {
            return this.wbClientFactoryBean.getTarget();
        }

    }

}
